#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/listener.h>

void listen_cb(struct evconnlistener* listener, evutil_socket_t sock,
    struct sockaddr* addr, int len, void* ptr);
void read_cb(struct bufferevent* bev, void* ctx);
void event_cb(struct bufferevent* bev, short events,void* ctx);

int main()
{
    //server info init
    struct sockaddr_in serv;
    memset(&serv, 0, sizeof (serv));
    serv.sin_family = AF_INET;
    serv.sin_port = htons(8888);
    serv.sin_addr.s_addr = htonl(INADDR_ANY);

    //创建事件处理框架
    struct event_base* base = event_base_new();

    //创建监听的套接字 - 绑定 - 监听 - 等待并接受连接
    struct evconnlistener* listen = evconnlistener_new_bind(base, listen_cb,
                            base, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
                            -1, (struct sockaddr*)&serv, sizeof (serv));

    //开始事件循环
    event_base_dispatch(base);

    //释放资源
    evconnlistener_free(listen);
    event_base_free(base);
    return 0;
}

void listen_cb(struct evconnlistener* listener, evutil_socket_t sock,
    struct sockaddr* addr, int len, void* ptr)
{
    struct event_base* base = (struct event_base*)ptr;
    //创建事件,设置回调函数,启动读缓冲区
    struct bufferevent* bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL);
    bufferevent_enable(bev, EV_READ);
}

void read_cb(struct bufferevent* bev, void* ctx)
{
    char buf[1024] = {0};
    size_t len = bufferevent_read(bev, buf, sizeof (buf));
    printf("rece data: %s\n", buf);

    bufferevent_write(bev, buf, len+1);
}

void event_cb(struct bufferevent* bev, short events,void* ctx)
{
    if (events & BEV_EVENT_EOF)
    {
        printf("connection closed...\n");
    }
    else if (events & BEV_EVENT_ERROR)
    {
        printf("some other error\n");
    }

    //释放bufferevent资源
    bufferevent_free(bev);
}
